package net.qhzw.geologr5.gis.service.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.geologr5.gis.common.framework.utils.JsonResult;
import net.qhzw.geologr5.gis.common.framework.utils.StringUtils;
import net.qhzw.geologr5.gis.service.system.component.FileTemplate;
import net.qhzw.geologr5.gis.service.system.entity.Software;
import net.qhzw.geologr5.gis.service.system.mapper.SoftwareMapper;
import net.qhzw.geologr5.gis.service.system.query.SoftwareQuery;
import net.qhzw.geologr5.gis.service.system.service.SoftwareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@Slf4j
public class SoftwareServiceImpl implements SoftwareService {


    @Autowired
    private SoftwareMapper softwareMapper;

    @Autowired
    private FileTemplate fileTemplate;


    /****
     * 软件列表查询
     * @param query
     * @return
     */
    @Override
    public JsonResult findSoftware(SoftwareQuery query) {
        log.error("软件列表查询==SoftwareServiceImpl==method:findSoftware==param:{}", JSON.toJSONString(query));
        Map<String, Object> result = new HashMap<>();
        PageHelper.startPage(query.getPage(), query.getLimit());
        try {
            List<Software> softwareList = softwareMapper.findSoftware(query);
            PageInfo<Software> pageInfo = new PageInfo<>(softwareList);
            result.put("list", pageInfo.getList());
            result.put("total", pageInfo.getTotal());
            return JsonResult.success(result);
        } catch (Exception e) {
            log.error("软件列表查询失败==SoftwareServiceImpl==method:findSoftware==errMag:{}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     * 新增|修改软件表
     * @param software
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult editorSoftware(Software software) {
        log.info("新增|修改软件表==SoftwareServiceImpl==method:editorSoftware==param:{}", JSON.toJSONString(software));
        try {
            if (StringUtils.isNull(software)) {
                return JsonResult.error("参数不能为空");
            }
            if (software.getId() != null && software.getId() > 0) {
                //修改
                int count = softwareMapper.updateById(software);
                if (count > 0) {
                    return JsonResult.success("修改成功");
                } else {
                    return JsonResult.error("修改失败");
                }
            }
            if (software.getUploadDate() == null) {
                software.setUploadDate(new Date());
            }
            software.setDownloadCount(0);
            int count = softwareMapper.insert(software);
            if (software.getUploadDate() == null) {
                software.setUploadDate(new Date());
            }
            if (count > 0) {
                return JsonResult.success("创建成功");
            } else {
                return JsonResult.error("创建失败");
            }
        } catch (Exception e) {
            log.error("新增|修改软件表失败==SoftwareServiceImpl==method:editorSoftware==errMsg:{}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }

    }


    /***
     * 删除软件表
     * @param ids
     * @return
     */
    @Override
    public JsonResult deleteSoftware(Integer[] ids) {
        log.info("删除软件表==SoftwareServiceImpl==method:deleteSoftware==param:{}", ids);
        try {
            if (ids == null || ids.length <= 0) {
                return JsonResult.error(400, "id参数:不能空");
            }
            List<Integer> idList = Arrays.asList(ids);
            int count = softwareMapper.deleteBatchIds(idList);
            if (count > 0) {
                return JsonResult.success("删除成功");
            } else {
                return JsonResult.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除软件表失败==SoftwareServiceImpl==method:deleteSoftware==errMsg:{}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }

    }


    /***
     * 软件上传
     * @param software
     * @param file
     * @return
     */
    @Override
    public JsonResult upload(Software software, MultipartFile file) {
        log.info("软件上传==SoftwareServiceImpl==method:upload==param: {}", JSON.toJSONString(software));
        try {
            log.info("软件上传==SoftwareServiceImpl==method:upload==文件名称: {}, 文件大小: {}", file.getOriginalFilename(), file.getSize());
            String fileUrl = fileTemplate.fileUpload(file);
            software.setDownloadCount(0);
            software.setSoftwareSize(getFileSize(file.getSize()));
            software.setUploadDate(new Date());
            software.setSoftwareUrl(fileUrl);
            int count = softwareMapper.insert(software);
            if (count > 0) {
                return JsonResult.success();
            }
            return JsonResult.error();
        } catch (Exception e) {
            log.info("软件上传失败==SoftwareServiceImpl==method:upload==errMsg: {}", e.getMessage());
            return JsonResult.error(e.getMessage());
        }
    }


    /***
     *把字节数B转化为KB、MB、GB
     * @param size
     * @return
     */
    private static String getFileSize(long size) {
        //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            return String.valueOf(size) + "B";
        } else {
            size = size / 1024;
        }
        //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (size < 1024) {
            return String.valueOf(size) + "KB";
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "MB";
        } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "GB";
        }
    }
}
